// Copyright(2011) ReportGear co., ltd.
/**
 * @fileOverview 业务基础开发平台-核心-语言扩展
 */

sps.provide('sps.lang');

(function() {
	var toString = Object.prototype.toString;
	var hasOwn = 'hasOwnProperty';
	var push = Array.prototype.push;
	var slice = Array.prototype.slice;
	var trim = String.prototype.trim;
	var indexOf = Array.prototype.indexOf;
	var lowerCase = String.prototype.toString;

	// JSON 正则表达式
	var rvalidchars = /^[\],:{}\s]*$/;
	var rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;
	var rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
	var rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g;

	// 裁剪字符串
			trimLeft = /^\s+/, trimRight = /\s+$/;

	sps.lang = {};
	/**
	 * 判断对象是否为指定类型,支持如下类型的判断:1、Null<br/> 2、Undifined<br/> 3、Number<br/>
	 * 4、String<br/> 5、Boolean<br/> 6、Object<br/> 7、Array<br/> 8、Regexp<br/>
	 * 9、Date<br/> 10、Function<br/>
	 */
	sps.lang.is =
			function(o, type) {
				var type = lowerCase.call(type);

				return (type == 'null' && o === null) || (type == typeof o) || (type == 'object' && o === Object(o))
						|| (type == 'number' && isFinite(o)) || (Array.isArray(o))
						|| toString.call(o).slice(8, -1).toLowerCase() == type;
			};

	/**
	 * 判断对象是否为值(Value)
	 * 
	 * @public
	 * @since 1.0
	 * @param o {Object} 判断的对象
	 * @return {Boolean} 如果不为 null/undefined/NaN || false 时为真
	 */
	sps.lang.isValue =
			function(o) {
				return (sps.lang.is(o, 'object') || sps.lang.is(o, 'string') || sps.lang.is(o, 'number') || sps.lang
						.is(o, 'boolean'));
			};
	/**
	 * 对象属性复制
	 * 
	 * @public
	 * @since 1.0
	 * @param {Object} obj 属性接收者
	 * @param {Object} config 属性提供值者
	 * @param {Object} [defaults] 默认属性提供者
	 * @return {Object} 对象
	 */
	sps.lang.apply = function(o, c, defaults) {
		if (defaults) {
			sps.lang.apply(o, defaults);
		}

		if (o && c && sps.lang.is(c, 'object')) {
			for ( var p in c) {
				if (c[hasOwn](p)) {
					o[p] = c[p];
				}
			}
		}
	};

	/**
	 * 函数备忘模式
	 * 
	 * @param {Function} fn 函数
	 * @param {Object} scope 上下文
	 * @param {Function} postProcesssor 取值后处理
	 */
	sps.lang.memoize = function(fn, scope, postprocessor) {
		function newf() {
			var arg = Array.prototype.slice.call(arguments, 0);
			var args = arg.join(",");
			var cache = newf.cache = newf.cache || {};
			var count = newf.count = newf.count || [];

			if (cache.hasOwnProperty(args)) {
				return postprocessor ? postprocessor(cache[args]) : cache[args];
			}

			/* LILO 保存1000个缓存值 */
			count.length >= 1e3 && delete cache[count.shift()];
			count.push(args);
			cache[args] = fn.apply(scope, arg);

			return postprocessor ? postprocessor(cache[args]) : cache[args];
		}

		return newf;
	};

	/* 扩充Function功能 */
	/**
	 * 绑定函数到上下文环境
	 * 
	 * @since 1.0
	 * @returns {Function} 函数
	 */
	Function.prototype.bind = function() {
		if (arguments.length < 2 && arguments[0] === undefined)
			return this;
		var __method = this, args = sps.$A(arguments), object = args.shift();
		return function() {
			return __method.apply(object, args.concat(sps.$A(arguments)));
		};
	};

	/**
	 * 绑定函数到事件监听
	 * 
	 * @since 1.0
	 * @returns {Function} 函数
	 */
	Function.prototype.bindAsEventListener = function() {
		var __method = this, args = sps.$A(arguments), object = args.shift();
		return function(event) {
			return __method.apply(object, [ event || window.event ].concat(args));
		};
	};
	/**
	 * 创建拦截器
	 */
	Function.prototype.createInterceptor = function(fcn, scope) {
		var method = this;
		return !sps.lang.is(fcn, 'function') ? this : function() {
			var me = this, args = arguments;
			// fcn.target = me;
				// fcn.method = method;
				return (fcn.apply(scope || me || window, args) !== false) ? method.apply(me || window, args) : null;
			};
	};

	/**
	 * 字符串首字母大写，其余小写
	 * 
	 * @returns {String} 字符串
	 */
	String.prototype.capitalize = function() {
		return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
	};

	/**
	 * 将-连接的字符串转换为驼峰的形式
	 */
	String.prototype.camelize = function() {
		var parts = this.split('-'), len = parts.length;
		if (len == 1)
			return parts[0];

		var camelized = this.charAt(0) == '-' ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1) : parts[0];

		for ( var i = 1; i < len; i++)
			camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);

		return camelized;
	};

	/* 扩充函数 */
	String.trim = trim ? function(text) {
		return text == null ? '' : trim.call(text);
	} : function(text) {
		return text == null ? '' : text.toString().replace(trimLeft, '').replace(trimRight, '');
	};

	/**
	 * 替换所有子串
	 * 
	 * @param {string} 原始字符串
	 * @param findText 查找字符串
	 * @param repText 替换的字符串
	 * @return {String} 替换后的字符串
	 */
	String.replaceAll = function(str, findText, repText) {
		return str.replace(new RegExp(findText, 'gm'), repText);
	};

	/**
	 * 格式化字符串
	 * 
	 * @example String.format('hello, My name is {0} {1}.',firstName, lastName);
	 * @return {String} 格式化后的字符串
	 */
	String.format = function(str) {
		if (arguments.length <= 1) {
			return str;
		} else {
			var str = str;
			for ( var i = 1; i < arguments.length; i++) {
				str = String.replaceAll(str, '\\{' + (i - 1) + '\\}', arguments[i]);
			}

			return str;
		}
	};

	/**
	 * 判断字符串是否以指定字符串开始
	 * 
	 * @param pattern 指定字符串
	 * @returns {Boolean} 以指定字符串开始则为true，否则为false
	 */
	String.startsWith = function(str, pattern) {
		return str.indexOf(pattern) === 0;
	};

	/**
	 * 判断字符串是否以指定字符串结束
	 * 
	 * @param pattern 指定字符串
	 * @returns {Boolean} 以指定字符串结束则为true，否则为false
	 */
	String.endsWith = function(str, pattern) {
		var d = this.length - pattern.length;
		return d >= 0 && str.lastIndexOf(pattern) === d;
	};

	/**
	 * 过滤Tags
	 * 
	 * @return {String} 字符串
	 */
	String.stripTags = function(str) {
		return str.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, '');
	};

	/**
	 * 替换HTML符号
	 * 
	 * @return {String} 字符串
	 */
	String.escapeHTML = function(str) {
		return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
	};

	/**
	 * 恢复HTML符号
	 * 
	 * @return {String} 字符串
	 */
	String.unescapeHTML =
			function(str) {
				return String.stripTags(str).replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&')
						.replace(/&quot;/g, '"');
			};

	String.include = function(str, pattern) {
		return str.indexOf(pattern) > -1;
	};
	/**
	 * 获取参数字符串，用&连接
	 * 
	 * @param {Object} params 参数对象
	 * @return {String} 参数字符串
	 */
	String.parameterStringfy = function(params) {
		var paramsArray = [];

		for ( var key in params) {
			var value = params[key];
			if ((value != null) && (typeof value != 'function')) {
				var encodedValue;
				if (typeof value == 'object' && value.constructor == Array) {
					var encodedItemArray = [];
					for ( var itemIndex = 0; itemIndex < value.length; itemIndex++) {
						encodedItemArray.push(encodeURIComponent(value[itemIndex]));
					}
					encodedValue = encodedItemArray.join(',');
				} else {
					encodedValue = encodeURIComponent(value);
				}
				paramsArray.push(encodeURIComponent(key) + '=' + encodedValue);
			}
		}

		return paramsArray.join('&');
	};

	/**
	 * 获取参数字符串，用"/"连接
	 * 
	 * @param {Object} params 参数对象
	 * @return {String} 参数字符串
	 */
	String.paramterRestfy = function(params) {
		var paramsArray = [];

		for ( var key in params) {
			var value = params[key];
			if ((value != null) && (typeof value != 'function')) {
				var encodedValue;
				// 处理数组类型的值
			if (typeof value == 'object' && value.constructor == Array) {
				var encodedItemArray = [];
				for ( var itemIndex = 0; itemIndex < value.length; itemIndex++) {
					encodedItemArray.push(encodeURIComponent(value[itemIndex]));
				}
				encodedValue = encodedItemArray.join(',');
			} else {
				encodedValue = encodeURIComponent(value);
			}
			paramsArray.push(encodedValue);
		}
	}

	return paramsArray.join('/');
}	;

	/**
	 * 可迭代数据转化为数组
	 * 
	 * @since 1.0
	 * @param {Object} o 可迭代数据
	 */
	sps.$A = function(o) {
		if (!o)
			return [];
		if (o.toArray)
			return o.toArray();
		var length = o.length, results = new Array(length);
		while (length--)
			results[length] = o[length];

		return results;
	};

	/**
	 * 可迭代数据转化为数组,如果是单个值，转化为数组的第一个值
	 * 
	 * @since 1.0
	 * @param {Object} o 可迭代数据
	 */
	sps.$SA = function(o) {
		result = sps.$A(o);

		if (o && !sps.lang.is(o, 'array')) {
			if (result[0] == undefined) {
				result[0] = o;
			}
		}

		return result;
	};

	/**
	 * 转化为数组
	 */
	Array.toArray = function(o) {
		var lang = sps.lang;
		if (o) {
			if (o.toArray) {
				return o.toArray();
			}

			if (lang.is(o, 'object') || lang.is(o, 'array')) {
				if (lang.is(o, 'array')) {
					return o;
				} else {
					if (o.length) {
						var length = o.length, results = new Array(length);
						while (length--) {
							results[length] = o[length];
						}

						return results;
					} else {
						return [ o ];
					}
				}
			}
		}

		return [];
	};

	Array.indexOf = function(arr, element) {
		for ( var i = 0, length = arr.length; i < length; i++) {
			if (arr[i] == element) {
				return i;
			}
		}

		return -1;
	};
	/**
	 * try 操作
	 */
	sps.Try = function() {
		var returnValue = null;

		for ( var i = 0; i < arguments.length; i++) {
			var lambda = arguments[i];
			try {
				returnValue = lambda();
				break;
			} catch (e) {
			}
		}

		return returnValue;
	};
}());